package indzcraft.loader;

import indzcraft.calc.Weapon;
import indzcraft.ranking.Database;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;


public class IndzCraftLoader {
	
	HashMap<String,Integer> items = new HashMap<String,Integer>();
	HashMap<String,Item> itemData = new HashMap<String,Item>();
	BaseStats base = new BaseStats();
	RaceDB raceDB = new RaceDB();
	GemDB gemDB = new GemDB();
	EnchantDB enchantDB = new EnchantDB();
	SocketBonusDB socketbonusDB = new SocketBonusDB();
	ReforgeDB reforgeDB = new ReforgeDB();
	ItemSetDB itemSetDB = new ItemSetDB();
	GearBuffDB gearBuffDB = new GearBuffDB();
	GlyphDB glyphDB = new GlyphDB();
	
	Equipment equipment = new Equipment();
	
	Database db;
	
	/*public IndzCraftLoader(String playername,String server,String region) throws JSONException{
		String json = load("http://"+region+".battle.net/api/wow/character/"+server+"/"+playername+"?fields=items,talents,stats");
		//System.out.println(json);
		// {  "lastModified":1311023887000,  "name":"Indz",  "realm":"Gorgonnash",  "class":4,  "race":3,  "gender":0,  "level":85,  "achievementPoints":11020,  "thumbnail":"gorgonnash/223/27359-avatar.jpg",  "items":{    "averageItemLevel":369,    "averageItemLevelEquipped":364,    "head":{      "id":59490,      "name":"Membrane of C'Thun",      "icon":"inv_helmet_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":68778,        "gem1":52211,        "enchant":4209      }    },    "neck":{      "id":59517,      "name":"Necklace of Strife",      "icon":"inv_misc_necklacea8",      "quality":4,      "tooltipParams":{        "reforge":168      }    },    "shoulder":{      "id":60302,      "name":"Wind Dancer's Spaulders",      "icon":"inv_shoulder_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":52220,        "enchant":4204,        "set":[60302,60301,60300,60298],        "reforge":146      }    },    "back":{      "id":71228,      "name":"Sleek Flamewrath Cloak",      "icon":"inv_cape_firelands_fireset_d_01",      "quality":4,      "tooltipParams":{        "enchant":1099,        "reforge":145      }    },    "chest":{      "id":60301,      "name":"Wind Dancer's Tunic",      "icon":"inv_chest_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":52212,        "gem1":52220,        "enchant":4102,        "set":[60302,60301,60300,60298],        "reforge":158      }    },    "shirt":{      "id":14617,      "name":"Sawbones Shirt",      "icon":"inv_shirt_red_01",      "quality":1,      "tooltipParams":{}    },    "tabard":{      "id":69210,      "name":"Renowned Guild Tabard",      "icon":"inv_epicguildtabard",      "quality":4,      "tooltipParams":{}    },    "wrist":{      "id":71130,      "name":"Flamebinder Bracers",      "icon":"inv_bracer_leather_raidrogue_j_01",      "quality":4,      "tooltipParams":{        "enchant":4190,        "reforge":145      }    },    "hands":{      "id":60298,      "name":"Wind Dancer's Gloves",      "icon":"inv_glove_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":52212,        "enchant":4068,        "set":[60302,60301,60300,60298],        "reforge":139      }    },    "waist":{      "id":71131,      "name":"Flamebinding Girdle",      "icon":"inv_belt_leather_raidrogue_j_01",      "quality":4,      "tooltipParams":{        "gem0":52220,        "gem1":52212,        "extraSocket":true      }    },    "legs":{      "id":60300,      "name":"Wind Dancer's Legguards",      "icon":"inv_pant_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":52211,        "gem1":52220,        "enchant":4126,        "set":[60302,60301,60300,60298],        "reforge":145      }    },    "feet":{      "id":58482,      "name":"Treads of Fleeting Joy",      "icon":"inv_boot_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":52220,        "enchant":4076,        "reforge":146      }    },    "finger1":{      "id":62362,      "name":"Signet of the Elder Council",      "icon":"inv_misc_diamondring2",      "quality":4,      "tooltipParams":{        "enchant":4079,        "reforge":165      }    },    "finger2":{      "id":70105,      "name":"Matoclaw's Band",      "icon":"inv_jewelry_ring_13",      "quality":4,      "tooltipParams":{        "enchant":4079,        "reforge":145      }    },    "trinket1":{      "id":62051,      "name":"Darkmoon Card: Hurricane",      "icon":"inv_inscription_tarot_hurricanecard",      "quality":4,      "tooltipParams":{}    },    "trinket2":{      "id":58181,      "name":"Fluid Death",      "icon":"ability_vehicle_liquidpyrite_blue",      "quality":4,      "tooltipParams":{        "reforge":138      }    },    "mainHand":{      "id":71782,      "name":"Shatterskull Bonecrusher",      "icon":"inv_mace_1h_firelandsraid_d_03",      "quality":4,      "tooltipParams":{        "enchant":4099,        "reforge":144      }    },    "offHand":{      "id":71787,      "name":"Entrail Disgorger",      "icon":"inv_knife_1h_firelandsraid_d_02",      "quality":4,      "tooltipParams":{        "enchant":4099,        "reforge":145      }    },    "ranged":{      "id":68608,      "name":"Dragonwreck Throwing Axe",      "icon":"inv_axe_110",      "quality":4,      "tooltipParams":{        "reforge":168      }    }  },  "talents":[    {      "selected":true,      "name":"Combat",      "icon":"ability_backstab",      "build":"032200000000000000023320303100320123210030000000000000000",      "trees":[        {          "points":"0322000000000000000",          "total":7        },        {          "points":"2332030310032012321",          "total":31        },        {          "points":"0030000000000000000",          "total":3        }      ],      "glyphs":{        "prime":[          {            "glyph":409,            "item":42972,            "name":"Glyph of Sinister Strike",            "icon":"spell_shadow_ritualofsacrifice"          },          {            "glyph":391,            "item":42954,            "name":"Glyph of Adrenaline Rush",            "icon":"spell_shadow_shadowworddominate"          },          {            "glyph":410,            "item":42973,            "name":"Glyph of Slice and Dice",            "icon":"ability_rogue_slicedice"          }        ],        "major":[          {            "glyph":400,            "item":42963,            "name":"Glyph of Feint",            "icon":"ability_rogue_feint"          },          {            "glyph":394,            "item":42957,            "name":"Glyph of Blade Flurry",            "icon":"ability_warrior_punishingblow"          },          {            "glyph":732,            "item":45767,            "name":"Glyph of Tricks of the Trade",            "icon":"ability_rogue_tricksofthetrade"          }        ],        "minor":[          {            "glyph":469,            "item":43380,            "name":"Glyph of Poisons",            "icon":"trade_brewpoison"          },          {            "glyph":467,            "item":43378,            "name":"Glyph of Safe Fall",            "icon":"inv_feather_01"          },          {            "glyph":468,            "item":43379,            "name":"Glyph of Blurred Speed",            "icon":"ability_rogue_sprint"          }        ]      }    },    {      "name":"Assassination",      "icon":"ability_rogue_eviscerate",      "build":"033323121332011002120000000000000000002032010000000000000",      "trees":[        {          "points":"0333231213320110021",          "total":31        },        {          "points":"2000000000000000000",          "total":2        },        {          "points":"2032010000000000000",          "total":8        }      ],      "glyphs":{        "prime":[          {            "glyph":733,            "item":45768,            "name":"Glyph of Mutilate",            "icon":"ability_rogue_shadowstrikes"          },          {            "glyph":393,            "item":42956,            "name":"Glyph of Backstab",            "icon":"ability_backstab"          },          {            "glyph":406,            "item":42969,            "name":"Glyph of Rupture",            "icon":"ability_rogue_rupture"          }        ],        "major":[          {            "glyph":731,            "item":45766,            "name":"Glyph of Fan of Knives",            "icon":"ability_rogue_fanofknives"          },          {            "glyph":732,            "item":45767,            "name":"Glyph of Tricks of the Trade",            "icon":"ability_rogue_tricksofthetrade"          },          {            "glyph":400,            "item":42963,            "name":"Glyph of Feint",            "icon":"ability_rogue_feint"          }        ],        "minor":[          {            "glyph":469,            "item":43380,            "name":"Glyph of Poisons",            "icon":"trade_brewpoison"          },          {            "glyph":467,            "item":43378,            "name":"Glyph of Safe Fall",            "icon":"inv_feather_01"          },          {            "glyph":465,            "item":43377,            "name":"Glyph of Pick Lock",            "icon":"spell_nature_moonkey"          }        ]      }    }  ]}
		JSONObject js = null;
		try {
			js = new JSONObject(json);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		//System.out.println(js.toString(1));
		JSONObject items = (JSONObject) js.get("items");
		for ( Iterator<?> i = items.keys(); i.hasNext(); )
		{
		  String s = (String) i.next();
		  Object item = items.get(s);
		  if(item instanceof Integer){
			  //System.out.println(s + ": (int) " + item.toString());
		  }
		  else{
			  int id = ((JSONObject)item).getInt("id");
			  //System.out.println(s + ": " +id);
			  this.items.put(s, id);
		  }
		}
		for( String name: this.items.keySet() )
	    {
	       System.out.println(name + ": "+ this.items.get(name));
	       JSONObject data = getItemDataWowHead(this.items.get(name));
	       itemData.put(name,data);
	       //System.out.println(data.toString(1));
	       
	       // gearBuffs:
	       int itemid = this.items.get(name);
	       if(itemid == 77945){
	    	   base.addGearBuff("dagger_combat_buff");
	       }
	       else if(itemid == 77947){
	    	   base.addGearBuff("dagger_combat_buff");
	       }
	    }
		JSONObject tooltip = null;
		for( String name: this.itemData.keySet() )
	    {
	       
	       JSONObject data = this.itemData.get(name);
	       //System.out.println(data.toString(1));
	       //System.out.println(name + ":.. ");
	       // SocketBonus Stats
	       boolean colorMatch = true;
	       JSONObject item = (JSONObject) items.get(name);
	       //System.out.println(item.toString(1));
	       Enchant e = null;
	       if(item.has("tooltipParams")){
	    	   tooltip = (JSONObject) item.get("tooltipParams");
	    	   //System.out.println(tooltip.toString(1));
	    	   if(tooltip.has("set")){
	    		   // yeah it's part of a set
	    		   String setname = itemSetDB.getItemSetByItemId(item.getInt("id"));
	    		   //System.out.println("setname:" + setname);
	    		   if(!base.getSetItems().containsKey(setname))
	    			   base.getSetItems().put(setname, 1);
	    		   else
	    			   base.getSetItems().put(setname, base.getSetItems().get(setname)+1);
	    	   }
	    	   if(tooltip.has("enchant")){
	    		   int enchantid = tooltip.getInt("enchant");
	    		   //System.out.println(name + " " + enchantid);
	    		   e = enchantDB.getEnchant(enchantid);
	    		   if(e != null){
	    			   System.out.println(name + ":.. " + e.getAgi());
	    			   baseIncreamentByEnchant(e);
	    		   }
	    	   }
	    	   if(tooltip.has("gem0")){
	    		   int gemid = tooltip.getInt("gem0");
	    		   Gem g = gemDB.getGem(gemid);
	    		   if(data.has("socket1") && (g.getType() != data.getInt("socket1")))
	    			   colorMatch = false;
	    		   baseIncreamentByGem(g);
	    	   }
	    	   if(tooltip.has("gem1")){
	    		   int gemid = tooltip.getInt("gem1");
	    		   Gem g = gemDB.getGem(gemid);
	    		   if(data.has("socket2") && (g.getType() != data.getInt("socket2")))
	    			   colorMatch = false;
	    		   baseIncreamentByGem(g);
	    	   }
	    	   if(tooltip.has("gem2")){
	    		   int gemid = tooltip.getInt("gem2");
	    		   Gem g = gemDB.getGem(gemid);
	    		   if(data.has("socket3") && (g.getType() != data.getInt("socket3")))
	    			   colorMatch = false;
	    		   baseIncreamentByGem(g);
	    	   }
	       }
	       SocketBonus sb = null;
	       if(data.has("nsockets") && colorMatch){
	    	   if(data.has("socketbonus")){
	    		   int socketbonusid = data.getInt("socketbonus");
	    		   //System.out.println(name + " " + socketbonusid);
	    		   sb = socketbonusDB.getSocketBonus(socketbonusid);
	    		   baseIncreamentBySocketBonus(sb);
	    	   }
	       }
	       baseIncreamentByItem(data,tooltip);
	       
	       if(data.has("dps")){
	    	   System.out.println(item.toString(1));
	    	   System.out.println(data.toString(1));
	    	   System.out.println(item.get("name"));
	    	   System.out.println("dps: " + data.getDouble("dps"));
	    	   System.out.println("speed: " + data.getDouble("speed"));
	    	   int subclass = data.getJSONObject("extra").getInt("subclass");
	    	   String type = "";
	    	   if(subclass == 15){
	    		   type = "dagger";
	    	   }else if(subclass == 4){
	    		   type = "mace";
	    	   }
	    	   // TODO identify all Subclasses
	    	   String enchant = "";
	    	   if(e != null){
	    		   enchant = e.getName();
	    	   }
	    	   if(name.equals("mainHand")){ // mainhand
	    		   base.setMH(new Weapon(data.getDouble("speed"),data.getDouble("dps"),type,enchant));
	    	   }else if(name.equals("offHand")){ // offhand
	    		   base.setOH(new Weapon(data.getDouble("speed"),data.getDouble("dps"),type,enchant));
	    	   }
	    	   // TODO handle thrown weapon, but fok isn't modeled
	       }
	    }
		// Race
		int raceid = js.getInt("race");
		RaceDB.Race race = raceDB.getRace(raceid);
		base.setRace(race.getName());
		baseIncreamentByRace(race);
		
		// talents TODO
		JSONArray talents = (JSONArray) js.get("talents");
		System.out.println(talents.length());
		for (int i = 0;i < talents.length(); i++ )
		{
			JSONObject spec = (JSONObject) talents.get(i);
			if(spec.has("selected") && spec.getBoolean("selected")){
				System.out.println("tree selected");
				//if(spec.getString("name").equals("Combat")){
					JSONArray trees = (JSONArray) spec.get("trees");
					String tree1 = trees.getJSONObject(0).getString("points").substring(0, 19);
					String tree2 = trees.getJSONObject(1).getString("points").substring(0, 19);
					String tree3 = trees.getJSONObject(2).getString("points").substring(0, 19);
					System.out.println(trees.getJSONObject(0).getString("points"));
					this.base.setTalents(tree1, tree2, tree3);
				//}
					this.base.setTalentsName(spec.getString("name"));
			}else{
				//System.out.println("tree not selected");
			}
		}
		
		
		System.out.println(js.getString("name") + " - Level " + js.getInt("level"));
		System.out.println("str: " + base.getStr());
		System.out.println("agi: " + base.getAgi());
		System.out.println("ap: " + base.getAp());
		System.out.println("crit: " + base.getCrit());
		System.out.println("hit: " + base.getHit());
		System.out.println("exp: " + base.getExp());
		System.out.println("haste: " + base.getHaste());
		System.out.println("mastery: " + base.getMastery());
		
		for( String name: this.base.getSetItems().keySet() )
	    {
			System.out.println(name + ": " + this.base.getSetItems().get(name) + " piece/s");
	    }
		for( String name: this.base.getGearBuffs() )
	    {
			System.out.print(name + ", ");
	    }
		System.out.println();
	}*/
	
	public void load2(String playername,String server,String region,boolean _new) throws JSONException{
		
		base = new BaseStats();
		equipment = new Equipment();
		
		String json = loadURL("http://"+region+".battle.net/api/wow/character/"+server+"/"+playername+"?fields=items,talents,stats,professions");
		//System.out.println(json.toString(1));
		JSONObject js = null;
		try {
			js = new JSONObject(json);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		System.out.println(js.toString(1));
		JSONObject items = (JSONObject) js.get("items");
		for ( Iterator<?> i = items.keys(); i.hasNext(); )
		{
			String s = (String) i.next();
			Object item = items.get(s);
			if(item instanceof Integer){
				//System.out.println(s + ": (int) " + item.toString());
			}
			else{
				int id = ((JSONObject)item).getInt("id");
				//System.out.println(s + ": " +id);
				this.items.put(s, id);
			}
		}
		for( String name: this.items.keySet() )
	    {
			int itemid = this.items.get(name);
			ItemEquiped item = getItemFromWOWHEAD(itemid);
			System.out.println(name + ": "+ itemid);
			
			// enchant etc.
			JSONObject iteme = new JSONObject();
			if(items.has(name))
				iteme = (JSONObject) items.get(name);
			
			JSONObject tooltip = null;
			Enchant e = null;
			if(iteme.has("tooltipParams")){
				tooltip = (JSONObject) iteme.get("tooltipParams");
			
				if(tooltip.has("enchant")){
					int enchantid = tooltip.getInt("enchant");
					e = enchantDB.getEnchant(enchantid);
					if(e != null){
						item.setEnchant(e);
					}
				} else {
					item.setEnchant(null);
				}
				if(tooltip.has("extraSocket") && tooltip.getBoolean("extraSocket")){
					int i = item.getNumSockets()-1;
					item.gemSlot[i] = "PRISMATIC";
				}else{
					int i = item.getNumSockets();
					if(i < item.gemSlot.length){
						item.gemSlot[i] = "";
					}
				}
				if(tooltip.has("gem0")){
	    		   int gemid = tooltip.getInt("gem0");
	    		   Gem g = gemDB.getGem(gemid);
	    		   item.setGem(0, g);
				}else {
					item.setGem(0, null);
				}
				if(tooltip.has("gem1")){
	    		   int gemid = tooltip.getInt("gem1");
	    		   Gem g = gemDB.getGem(gemid);
	    		   item.setGem(1, g);
				}else {
					item.setGem(1, null);
				}
				if(tooltip.has("gem2")){
	    		   int gemid = tooltip.getInt("gem2");
	    		   Gem g = gemDB.getGem(gemid);
	    		   item.setGem(2, g);
				}else {
					item.setGem(2, null);
				}
				if(tooltip.has("reforge")){
					int reforgeid = tooltip.getInt("reforge");
					//System.out.println("reforge_id: " + reforgeid);
					Reforge r = reforgeDB.getReforge(reforgeid);
					item.setReforge(r);
				}else {
					item.setReforge(new Reforge());
				}
			}
	       
			if(item.dps > 0){
				int subclass = item.getItemSubClass();
				String type = "";
				if(subclass == 15){
					type = "dagger";
				}else if(subclass == 4){
					type = "mace";
				}else if(subclass == 7){
					type = "sword";
				}else if(subclass == 0){
					type = "axe";
				}else if(subclass == 13){
					type = "fist";
				}
				// TODO identify all Subclasses
				String enchant = "";
				if(e != null){
					enchant = e.getName(); 
				}
				if(name.equals("mainHand")){ // mainhand
					base.setMH(new Weapon(item.speed,item.dps,type,enchant));
				}else if(name.equals("offHand")){ // offhand
					base.setOH(new Weapon(item.speed,item.dps,type,enchant));
				}
			}
			
			if(item.getGearBuff() != null)
				base.addGearBuff(item.getGearBuff());
			
			equipment.put(name, item);
			this.db.put(item.getId(), item);
	    }
		
		// Race
		//System.out.println("race: " + js.getInt("race"));
		base.setRace(raceDB.getRace(js.getInt("race")).getName());
		
		// Professions
		JSONObject profession = js.getJSONObject("professions");
		JSONArray professions = profession.getJSONArray("primary");
		for (int i = 0;i < professions.length(); i++ )
		{
			JSONObject prof = (JSONObject) professions.get(i);
			//System.out.println(prof.getString("name"));
			base.addProfession(prof.getString("name"));
		}
		
		// talents
		JSONArray talents = (JSONArray) js.get("talents");
		//System.out.println(talents.length());
		for (int i = 0;i < talents.length(); i++ )
		{
			JSONObject spec = (JSONObject) talents.get(i);
			//System.out.println(spec.toString(1));
			if((spec.has("selected") && spec.getBoolean("selected"))){
				System.out.println("tree: " + spec.getString("name"));
				//if(spec.getString("name").equals("Combat")){
					JSONArray trees = (JSONArray) spec.get("trees");
					String tree1 = trees.getJSONObject(0).getString("points").substring(0, 19);
					String tree2 = trees.getJSONObject(1).getString("points").substring(0, 19);
					String tree3 = trees.getJSONObject(2).getString("points").substring(0, 19);

					this.base.setTalents(tree1, tree2, tree3);
					this.base.setTalentsName(spec.getString("name"));
					
					JSONObject glyphs = (JSONObject) spec.get("glyphs");
					JSONArray prime = glyphs.getJSONArray("prime");
					int prime1 = prime.getJSONObject(0).getInt("glyph");
					int prime2 = prime.getJSONObject(1).getInt("glyph");
					int prime3 = prime.getJSONObject(2).getInt("glyph");
					
					JSONArray major = glyphs.getJSONArray("major");
					int major1 = major.getJSONObject(0).getInt("glyph");
					int major2 = major.getJSONObject(1).getInt("glyph");
					int major3 = major.getJSONObject(2).getInt("glyph");
					
					this.base.addGlyph(glyphDB.getGlyph(prime1).getName());
					this.base.addGlyph(glyphDB.getGlyph(prime2).getName());
					this.base.addGlyph(glyphDB.getGlyph(prime3).getName());
					this.base.addGlyph(glyphDB.getGlyph(major1).getName());
					this.base.addGlyph(glyphDB.getGlyph(major2).getName());
					this.base.addGlyph(glyphDB.getGlyph(major3).getName());
				//}
			}else{
				//System.out.println("tree not selected");
				JSONArray trees = (JSONArray) spec.get("trees");
				String tree1 = trees.getJSONObject(0).getString("points").substring(0, 19);
				String tree2 = trees.getJSONObject(1).getString("points").substring(0, 19);
				String tree3 = trees.getJSONObject(2).getString("points").substring(0, 19);
				
				this.base.setOffTalents(tree1, tree2, tree3);
				this.base.setOffTalentsName(spec.getString("name"));
				
				JSONObject glyphs = (JSONObject) spec.get("glyphs");
				JSONArray prime = glyphs.getJSONArray("prime");
				int prime1 = prime.getJSONObject(0).getInt("glyph");
				int prime2 = prime.getJSONObject(1).getInt("glyph");
				int prime3 = prime.getJSONObject(2).getInt("glyph");
				
				JSONArray major = glyphs.getJSONArray("major");
				int major1 = major.getJSONObject(0).getInt("glyph");
				int major2 = major.getJSONObject(1).getInt("glyph");
				int major3 = major.getJSONObject(2).getInt("glyph");
				
				this.base.addOffGlyph(glyphDB.getGlyph(prime1).getName());
				this.base.addOffGlyph(glyphDB.getGlyph(prime2).getName());
				this.base.addOffGlyph(glyphDB.getGlyph(prime3).getName());
				this.base.addOffGlyph(glyphDB.getGlyph(major1).getName());
				this.base.addOffGlyph(glyphDB.getGlyph(major2).getName());
				this.base.addOffGlyph(glyphDB.getGlyph(major3).getName());
			}
		}
		
		JSONObject stats = (JSONObject) js.get("stats");
		//System.out.println(stats.toString(1));
		
		base.incExp(stats.getInt("expertiseRating"));
		double agi = stats.getInt("agi")/1.05;
		if(this.base.getTalentsName().equals("Subtlety")){
			agi = agi/1.3;
		}
		base.incAgi((int)Math.ceil(agi));
		//base.incAgi(stats.getInt("agi"));
		base.incStr(stats.getInt("str"));
		base.incCrit(stats.getInt("critRating"));
		base.incHaste(stats.getInt("hasteRating"));
		base.incHit(stats.getInt("hitRating"));
		base.incMastery(stats.getInt("masteryRating"));
		base.incAp(190);
		
		System.out.println(js.getString("name") + " - Level " + js.getInt("level"));
		System.out.println("str: " + base.getStr());
		System.out.println("agi: " + base.getAgi());
		System.out.println("ap: " + base.getAp());
		System.out.println("crit: " + base.getCrit());
		System.out.println("hit: " + base.getHit());
		System.out.println("exp: " + base.getExp());
		System.out.println("haste: " + base.getHaste());
		System.out.println("mastery: " + base.getMastery());
		
		for( String name: this.base.getSetItems().keySet() )
	    {
			System.out.println(name + ": " + this.base.getSetItems().get(name) + " piece/s");
	    }
		for( String name: this.base.getGearBuffs() )
	    {
			System.out.print(name + ", ");
	    }
		System.out.println();
	}
	
public void load(String playername,String server,String region,boolean _new) throws JSONException{
		
		base = new BaseStats();
		equipment = new Equipment();
		
		String json = loadURL("http://"+region+".battle.net/api/wow/character/"+server+"/"+playername+"?fields=items,talents,stats");
		//System.out.println(json.toString(1));
		// {  "lastModified":1311023887000,  "name":"Indz",  "realm":"Gorgonnash",  "class":4,  "race":3,  "gender":0,  "level":85,  "achievementPoints":11020,  "thumbnail":"gorgonnash/223/27359-avatar.jpg",  "items":{    "averageItemLevel":369,    "averageItemLevelEquipped":364,    "head":{      "id":59490,      "name":"Membrane of C'Thun",      "icon":"inv_helmet_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":68778,        "gem1":52211,        "enchant":4209      }    },    "neck":{      "id":59517,      "name":"Necklace of Strife",      "icon":"inv_misc_necklacea8",      "quality":4,      "tooltipParams":{        "reforge":168      }    },    "shoulder":{      "id":60302,      "name":"Wind Dancer's Spaulders",      "icon":"inv_shoulder_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":52220,        "enchant":4204,        "set":[60302,60301,60300,60298],        "reforge":146      }    },    "back":{      "id":71228,      "name":"Sleek Flamewrath Cloak",      "icon":"inv_cape_firelands_fireset_d_01",      "quality":4,      "tooltipParams":{        "enchant":1099,        "reforge":145      }    },    "chest":{      "id":60301,      "name":"Wind Dancer's Tunic",      "icon":"inv_chest_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":52212,        "gem1":52220,        "enchant":4102,        "set":[60302,60301,60300,60298],        "reforge":158      }    },    "shirt":{      "id":14617,      "name":"Sawbones Shirt",      "icon":"inv_shirt_red_01",      "quality":1,      "tooltipParams":{}    },    "tabard":{      "id":69210,      "name":"Renowned Guild Tabard",      "icon":"inv_epicguildtabard",      "quality":4,      "tooltipParams":{}    },    "wrist":{      "id":71130,      "name":"Flamebinder Bracers",      "icon":"inv_bracer_leather_raidrogue_j_01",      "quality":4,      "tooltipParams":{        "enchant":4190,        "reforge":145      }    },    "hands":{      "id":60298,      "name":"Wind Dancer's Gloves",      "icon":"inv_glove_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":52212,        "enchant":4068,        "set":[60302,60301,60300,60298],        "reforge":139      }    },    "waist":{      "id":71131,      "name":"Flamebinding Girdle",      "icon":"inv_belt_leather_raidrogue_j_01",      "quality":4,      "tooltipParams":{        "gem0":52220,        "gem1":52212,        "extraSocket":true      }    },    "legs":{      "id":60300,      "name":"Wind Dancer's Legguards",      "icon":"inv_pant_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":52211,        "gem1":52220,        "enchant":4126,        "set":[60302,60301,60300,60298],        "reforge":145      }    },    "feet":{      "id":58482,      "name":"Treads of Fleeting Joy",      "icon":"inv_boot_leatherraidrogue_i_01",      "quality":4,      "tooltipParams":{        "gem0":52220,        "enchant":4076,        "reforge":146      }    },    "finger1":{      "id":62362,      "name":"Signet of the Elder Council",      "icon":"inv_misc_diamondring2",      "quality":4,      "tooltipParams":{        "enchant":4079,        "reforge":165      }    },    "finger2":{      "id":70105,      "name":"Matoclaw's Band",      "icon":"inv_jewelry_ring_13",      "quality":4,      "tooltipParams":{        "enchant":4079,        "reforge":145      }    },    "trinket1":{      "id":62051,      "name":"Darkmoon Card: Hurricane",      "icon":"inv_inscription_tarot_hurricanecard",      "quality":4,      "tooltipParams":{}    },    "trinket2":{      "id":58181,      "name":"Fluid Death",      "icon":"ability_vehicle_liquidpyrite_blue",      "quality":4,      "tooltipParams":{        "reforge":138      }    },    "mainHand":{      "id":71782,      "name":"Shatterskull Bonecrusher",      "icon":"inv_mace_1h_firelandsraid_d_03",      "quality":4,      "tooltipParams":{        "enchant":4099,        "reforge":144      }    },    "offHand":{      "id":71787,      "name":"Entrail Disgorger",      "icon":"inv_knife_1h_firelandsraid_d_02",      "quality":4,      "tooltipParams":{        "enchant":4099,        "reforge":145      }    },    "ranged":{      "id":68608,      "name":"Dragonwreck Throwing Axe",      "icon":"inv_axe_110",      "quality":4,      "tooltipParams":{        "reforge":168      }    }  },  "talents":[    {      "selected":true,      "name":"Combat",      "icon":"ability_backstab",      "build":"032200000000000000023320303100320123210030000000000000000",      "trees":[        {          "points":"0322000000000000000",          "total":7        },        {          "points":"2332030310032012321",          "total":31        },        {          "points":"0030000000000000000",          "total":3        }      ],      "glyphs":{        "prime":[          {            "glyph":409,            "item":42972,            "name":"Glyph of Sinister Strike",            "icon":"spell_shadow_ritualofsacrifice"          },          {            "glyph":391,            "item":42954,            "name":"Glyph of Adrenaline Rush",            "icon":"spell_shadow_shadowworddominate"          },          {            "glyph":410,            "item":42973,            "name":"Glyph of Slice and Dice",            "icon":"ability_rogue_slicedice"          }        ],        "major":[          {            "glyph":400,            "item":42963,            "name":"Glyph of Feint",            "icon":"ability_rogue_feint"          },          {            "glyph":394,            "item":42957,            "name":"Glyph of Blade Flurry",            "icon":"ability_warrior_punishingblow"          },          {            "glyph":732,            "item":45767,            "name":"Glyph of Tricks of the Trade",            "icon":"ability_rogue_tricksofthetrade"          }        ],        "minor":[          {            "glyph":469,            "item":43380,            "name":"Glyph of Poisons",            "icon":"trade_brewpoison"          },          {            "glyph":467,            "item":43378,            "name":"Glyph of Safe Fall",            "icon":"inv_feather_01"          },          {            "glyph":468,            "item":43379,            "name":"Glyph of Blurred Speed",            "icon":"ability_rogue_sprint"          }        ]      }    },    {      "name":"Assassination",      "icon":"ability_rogue_eviscerate",      "build":"033323121332011002120000000000000000002032010000000000000",      "trees":[        {          "points":"0333231213320110021",          "total":31        },        {          "points":"2000000000000000000",          "total":2        },        {          "points":"2032010000000000000",          "total":8        }      ],      "glyphs":{        "prime":[          {            "glyph":733,            "item":45768,            "name":"Glyph of Mutilate",            "icon":"ability_rogue_shadowstrikes"          },          {            "glyph":393,            "item":42956,            "name":"Glyph of Backstab",            "icon":"ability_backstab"          },          {            "glyph":406,            "item":42969,            "name":"Glyph of Rupture",            "icon":"ability_rogue_rupture"          }        ],        "major":[          {            "glyph":731,            "item":45766,            "name":"Glyph of Fan of Knives",            "icon":"ability_rogue_fanofknives"          },          {            "glyph":732,            "item":45767,            "name":"Glyph of Tricks of the Trade",            "icon":"ability_rogue_tricksofthetrade"          },          {            "glyph":400,            "item":42963,            "name":"Glyph of Feint",            "icon":"ability_rogue_feint"          }        ],        "minor":[          {            "glyph":469,            "item":43380,            "name":"Glyph of Poisons",            "icon":"trade_brewpoison"          },          {            "glyph":467,            "item":43378,            "name":"Glyph of Safe Fall",            "icon":"inv_feather_01"          },          {            "glyph":465,            "item":43377,            "name":"Glyph of Pick Lock",            "icon":"spell_nature_moonkey"          }        ]      }    }  ]}
		JSONObject js = null;
		try {
			js = new JSONObject(json);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		//System.out.println(js.toString(1));
		JSONObject items = (JSONObject) js.get("items");
		for ( Iterator<?> i = items.keys(); i.hasNext(); )
		{
		  String s = (String) i.next();
		  Object item = items.get(s);
		  if(item instanceof Integer){
			  //System.out.println(s + ": (int) " + item.toString());
		  }
		  else{
			  int id = ((JSONObject)item).getInt("id");
			  //System.out.println(s + ": " +id);
			  this.items.put(s, id);
		  }
		}
		for( String name: this.items.keySet() )
	    {
			int itemid = this.items.get(name);
			System.out.println(name + ": "+ itemid);
			
			//JSONObject data = getItemDataBattleNet(itemid);
			Item item = db.get(itemid);
			//System.out.println(item.getGearBuff());
			itemData.put(name,item);
			//System.out.println(data.toString(1));
			// gearbuffs, trinkets etc. special stuff
			/*if(data.getJSONArray("itemSpells").length() > 0){
				GearBuffDB.GearBuff gearbuff = gearBuffDB.getGearBuff(itemid);
				if(gearbuff != null)
					base.addGearBuff(gearbuff.getName());
			}*/
	    }
		JSONObject tooltip = null;
		for( String name: this.itemData.keySet() )
	    {
			ItemEquiped data = (ItemEquiped) this.itemData.get(name);
			equipment.put(name, data);
			
			JSONObject item = new JSONObject();
			if(items.has(name))
				item = (JSONObject) items.get(name);
			//System.out.println(item.toString(1));
			Enchant e = null;
			if(item.has("tooltipParams")){
				tooltip = (JSONObject) item.get("tooltipParams");
				//System.out.println(tooltip.toString(1));
				if(tooltip.has("set")){
					// yeah it's part of a set
					String setname = itemSetDB.getItemSetByItemId(item.getInt("id"));
					//System.out.println("setname:" + setname);
					equipment.get(name).setSet(setname);
					data.setSet(setname);
					if(!base.getSetItems().containsKey(setname))
						base.getSetItems().put(setname, 1);
					else
						base.getSetItems().put(setname, base.getSetItems().get(setname)+1);
	    	   }
	    	   if(tooltip.has("enchant")){
	    		   int enchantid = tooltip.getInt("enchant");
	    		   //System.out.println(name + " " + enchantid);
	    		   e = enchantDB.getEnchant(enchantid);
	    		   if(e != null){
	    			   //System.out.println(name + ":.. " + e.getAgi());
	    			   //baseIncreamentByEnchant(e);
	    			   equipment.get(name).setEnchant(e);
	    			   data.setEnchant(e);
	    		   }
	    	   }else{
	    		   equipment.get(name).setEnchant(null);
    			   data.setEnchant(null);
	    	   }
			}
			if(data.getId() == 71131 || name.equals("waist")){
				System.out.println("num Sockets: "+ data.getNumSockets());
			}
			if(tooltip.has("extraSocket") && tooltip.getBoolean("extraSocket")){
				int i = data.getNumSockets()-1;
				equipment.get(name).gemSlot[i] = "PRISMATIC";
				data.gemSlot[i] = "PRISMATIC";
			}else{
				int i = data.getNumSockets();
				if(i < equipment.get(name).gemSlot.length){
					equipment.get(name).gemSlot[i] = "";
					data.gemSlot[i] = "";
				}
			}
			if(tooltip.has("gem0")){
    		   int gemid = tooltip.getInt("gem0");
    		   Gem g = gemDB.getGem(gemid);
    		   equipment.get(name).setGem(0, g);
    		   data.setGem(0, g);
			}else {
				equipment.get(name).setGem(0,null);
				data.setGem(0, null);
			}
			if(tooltip.has("gem1")){
    		   int gemid = tooltip.getInt("gem1");
    		   Gem g = gemDB.getGem(gemid);
    		   equipment.get(name).setGem(1, g);
    		   data.setGem(1, g);
			}else {
				equipment.get(name).setGem(1,null);
				data.setGem(1, null);
			}
			if(tooltip.has("gem2")){
    		   int gemid = tooltip.getInt("gem2");
    		   Gem g = gemDB.getGem(gemid);
    		   equipment.get(name).setGem(2, g);
    		   data.setGem(2, g);
			}else {
				equipment.get(name).setGem(2,null);
				data.setGem(2, null);
			}
			if(tooltip.has("reforge")){
				int reforgeid = tooltip.getInt("reforge");
				//System.out.println("reforge_id: " + reforgeid);
				Reforge r = reforgeDB.getReforge(reforgeid);
				equipment.get(name).setReforge(r);
				data.setReforge(r);
			}else {
				equipment.get(name).setReforge(new Reforge());
				data.setReforge(new Reforge());
			}
	       
			if(data.dps > 0){
				int subclass = data.getItemSubClass();
				System.out.println(data.getName() + " " + subclass);
				String type = "";
				if(subclass == 15){
					type = "dagger";
				}else if(subclass == 4){
					type = "mace";
				}else if(subclass == 7){
					type = "sword";
				}else if(subclass == 0){
					type = "axe";
				}else if(subclass == 13){
					type = "fist";
				}
				// TODO identify all Subclasses
				String enchant = "";
				if(e != null){
					enchant = e.getName(); 
				}
				if(name.equals("mainHand")){ // mainhand
					base.setMH(new Weapon(data.speed,data.dps,type,enchant));
				}else if(name.equals("offHand")){ // offhand
					base.setOH(new Weapon(data.speed,data.dps,type,enchant));
				}
			}
			if(data.getGearBuff() != null)
				base.addGearBuff(data.getGearBuff());
			//this.db.put(data.getId(),data);
			equipment.put(name, data);
			this.itemData.put(name, data);
		}
		
		equipment.print();
		
		// Race
		System.out.println("race: " + js.getInt("race"));
		int raceid = js.getInt("race");
		Race race = raceDB.getRace(raceid);
		base.setRace(race.getName());
		//baseIncreamentByRace(race);
		
		// Professions
		
		
		// talents TODO
		JSONArray talents = (JSONArray) js.get("talents");
		//System.out.println(talents.length());
		for (int i = 0;i < talents.length(); i++ )
		{
			JSONObject spec = (JSONObject) talents.get(i);
			//System.out.println(spec.toString(1));
			if((spec.has("selected") && spec.getBoolean("selected"))){
				System.out.println("tree: " + spec.getString("name"));
				//if(spec.getString("name").equals("Combat")){
					JSONArray trees = (JSONArray) spec.get("trees");
					String tree1 = trees.getJSONObject(0).getString("points").substring(0, 19);
					String tree2 = trees.getJSONObject(1).getString("points").substring(0, 19);
					String tree3 = trees.getJSONObject(2).getString("points").substring(0, 19);
					//System.out.println(tree1);
					//System.out.println(tree2);
					//System.out.println(tree3);
					this.base.setTalents(tree1, tree2, tree3);
					this.base.setTalentsName(spec.getString("name"));
				//}
			}else{
				//System.out.println("tree not selected");
				JSONArray trees = (JSONArray) spec.get("trees");
				String tree1 = trees.getJSONObject(0).getString("points").substring(0, 19);
				String tree2 = trees.getJSONObject(1).getString("points").substring(0, 19);
				String tree3 = trees.getJSONObject(2).getString("points").substring(0, 19);
				
				this.base.setOffTalents(tree1, tree2, tree3);
				this.base.setOffTalentsName(spec.getString("name"));
			}
		}
		
		JSONObject stats = (JSONObject) js.get("stats");
		//System.out.println(stats.toString(1));
		
		base.incExp(stats.getInt("expertiseRating"));
		double agi = stats.getInt("agi")/1.05;
		if(this.base.getTalentsName().equals("Subtlety")){
			agi = agi/1.3;
		}
		base.incAgi((int)Math.ceil(agi));
		//base.incAgi(stats.getInt("agi"));
		base.incStr(stats.getInt("str"));
		base.incCrit(stats.getInt("critRating"));
		base.incHaste(stats.getInt("hasteRating"));
		base.incHit(stats.getInt("hitRating"));
		base.incMastery(stats.getInt("masteryRating"));
		base.incAp(190);
		
		System.out.println(js.getString("name") + " - Level " + js.getInt("level"));
		System.out.println("str: " + base.getStr());
		System.out.println("agi: " + base.getAgi());
		System.out.println("ap: " + base.getAp());
		System.out.println("crit: " + base.getCrit());
		System.out.println("hit: " + base.getHit());
		System.out.println("exp: " + base.getExp());
		System.out.println("haste: " + base.getHaste());
		System.out.println("mastery: " + base.getMastery());
		
		for( String name: this.base.getSetItems().keySet() )
	    {
			System.out.println(name + ": " + this.base.getSetItems().get(name) + " piece/s");
	    }
		for( String name: this.base.getGearBuffs() )
	    {
			System.out.print(name + ", ");
	    }
		System.out.println();
	}
	
	public IndzCraftLoader() {

	}

	/*private void baseIncreamentByRace(RaceDB.Race b) {
		base.incStr(b.getStr());
		base.incAgi(b.getAgi());
	}
	
	private void baseIncreamentByGem(Gem b) {
		base.incAgi(b.getAgi());
		base.incHaste(b.getHaste());
		base.incHit(b.getHit());
	}
	
	private void baseIncreamentByEnchant(Enchant b) {
		base.incStr(b.getStr());
		base.incAgi(b.getAgi());
		base.incHaste(b.getHaste());
		base.incHit(b.getHit());
		base.incAp(b.getAp());
		base.incCrit(b.getCrit());
		base.incExp(b.getExp());
		base.incMastery(b.getMastery());
	}
	
	private void baseIncreamentBySocketBonus(SocketBonus b) {
		base.incAgi(b.getAgi());
		base.incHaste(b.getHaste());
		base.incHit(b.getHit());
		base.incAp(b.getAp());
		base.incCrit(b.getCrit());
		base.incExp(b.getExp());
		base.incMastery(b.getMastery());
	}
	
	private void baseIncreamentByItem(JSONObject b,JSONObject tooltip) throws JSONException {
		
		// random items checking, not the best place obviously, but for the first time it works
		if(tooltip.has("suffix")){
			System.out.println("Random Item Found");
			int suffixid = tooltip.getInt("suffix");
			if(suffixid == -133){
				b.put("critstrkrtng",170);
				b.put("hitrtng",170);
				b.put("agi", 256);
			}
		}
		
		int value = 0;
		
		int add_haste = 0;
		int add_hit = 0;
		int add_crit = 0;
		int add_exp = 0;
		int add_mastery = 0;
		// reforge is best here
		Reforge r = null;
		if(tooltip.has("reforge")){
			int reforgeid = tooltip.getInt("reforge");
			//System.out.println("reforge_id: " + reforgeid);
			r = reforgeDB.getReforge(reforgeid);
			//System.out.println(r.getFrom() + " -> " + r.getTo());
			if(r.getFrom() == "Haste Rating"){
				value = (int) Math.floor(b.getInt("hastertng")*0.4);
				add_haste = value;
			}
			else if(r.getFrom() == "Hit Rating"){
				value = (int) Math.floor(b.getInt("hitrtng")*0.4);
				add_hit = value;
			}
			else if(r.getFrom() == "Crit Rating"){
				value = (int) Math.floor(b.getInt("critstrkrtng")*0.4);
				add_crit = value;
			}
			else if(r.getFrom() == "Expertise Rating"){
				value = (int) Math.floor(b.getInt("exprtng")*0.4);
				add_exp = value;
			}
			else if(r.getFrom() == "Mastery"){
				value = (int) Math.floor(b.getInt("mastrtng")*0.4);
				add_mastery = value;
			}
			//System.out.println("reforge_value: " + value);
		}
		
		if(b.has("agi"))
			base.incAgi(b.getInt("agi"));
		if(b.has("hastertng"))
			base.incHaste(b.getInt("hastertng")-add_haste);
		if(b.has("hitrtng"))
			base.incHit(b.getInt("hitrtng")-add_hit);
		if(b.has("critstrkrtng"))
			base.incCrit(b.getInt("critstrkrtng")-add_crit);
		if(b.has("exprtng"))
			base.incExp(b.getInt("exprtng")-add_exp);
		if(b.has("mastrtng"))
			base.incMastery(b.getInt("mastrtng")-add_mastery);
		
		if(r != null){
			if(r.getTo() == "Haste Rating"){
				base.incHaste(value);
			}
			else if(r.getTo() == "Hit Rating"){
				base.incHit(value);
			}
			else if(r.getTo() == "Crit Rating"){
				base.incCrit(value);
			}
			else if(r.getTo() == "Expertise Rating"){
				base.incExp(value);
			}
			else if(r.getTo() == "Mastery"){
				base.incMastery(value);
			}
		}
	}*/

	private String loadURL(String url) {
		
		InputStream is = null;
		BufferedReader rd = null;
		try {
			is = new URL(url).openStream();
			rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		String cp = "";
		StringBuilder sb = new StringBuilder();
		try {
			while ((cp = rd.readLine()) != null) {
			      sb.append(cp);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return sb.toString();
	}
	
	public static String getCharacterDataFromElement(Element e) {
		Node child = e.getFirstChild();
		if (child instanceof CharacterData) {
		   CharacterData cd = (CharacterData) child;
		   return cd.getData();
		}
		return "?";
	}
	
	public SocketBonus getSocketBonus(int item_id){
		SocketBonus sb = null;
		try {
			JSONObject data = getItemDataWowHead(item_id);
			//System.out.println(data.toString(1));
			if(data.has("socketbonus")){
				int socketbonusid = data.getInt("socketbonus");
				sb = socketbonusDB.getSocketBonus(socketbonusid);
			}
		}
		catch (Exception e) {
	        e.printStackTrace();
	    }
		return sb;
	}
	
	public JSONObject getItemDataWowHead(int item_id){
		
		JSONObject stats = null;
		String json = "";
		
		File file = new File("./wowhead/"+item_id+".xml");
		if(!file.exists()){
			json = loadURL("http://www.wowhead.com/item=" + item_id + "&xml");
		
			try {
				//System.out.println("Write to db: " + id);
				//File file = new File("./wowhead/"+item_id+".xml");
				PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
				out.write(json);
				out.flush();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		else{
			BufferedReader in;
			try {
				in = (new BufferedReader(new FileReader(file)));
				json = in.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		//System.out.println(json);
		try {
	        DocumentBuilderFactory dbf =
	            DocumentBuilderFactory.newInstance();
	        DocumentBuilder db = dbf.newDocumentBuilder();
	        InputSource is = new InputSource();
	        is.setCharacterStream(new StringReader(json));

	        Document doc = db.parse(is);
	        NodeList nodes = doc.getElementsByTagName("jsonEquip");
	        NodeList nodes2 = doc.getElementsByTagName("json");
	        
	        NodeList nodes3 = doc.getElementsByTagName("name");
	        NodeList nodes4 = doc.getElementsByTagName("icon");

	        Element element = (Element) nodes.item(0);
      
	        stats = new JSONObject("{" + element.getTextContent()+ "}");
	        Element element2 = (Element) nodes2.item(0);
	        JSONObject stats2 = new JSONObject("{" + element2.getTextContent()+ "}");
	        stats.put("extra", stats2);
           
	        Element element3 = (Element) nodes3.item(0);
	        String stats3 = element3.getTextContent();
	        stats.put("name", stats3);
	        
	        Element element4 = (Element) nodes4.item(0);
	        String stats4 = element4.getTextContent();
	        stats.put("icon", stats4);
	    }
	    catch (Exception e) {
	        e.printStackTrace();
	    }
	    return stats;
	}
	
	public String getWoWHeadTooltip(int item_id){
//		BufferedReader in =(new BufferedReader(new FileReader(file)));
//		String s = in.readLine();
		
		String tooltip = "";
		String json = "";
		File file = new File("./wowhead/"+item_id+".xml");
		if(file.exists()){
			BufferedReader in;
			try {
				in = (new BufferedReader(new FileReader(file)));
				json = in.readLine();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else{
		
			json = loadURL("http://www.wowhead.com/item=" + item_id + "&xml");
			
			try {
				//System.out.println("Write to db: " + id);
				file = new File("./wowhead/"+item_id+".xml");
				PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
				out.write(json);
				out.flush();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		//System.out.println(json);
		try {
	        DocumentBuilderFactory dbf =
	            DocumentBuilderFactory.newInstance();
	        DocumentBuilder db = dbf.newDocumentBuilder();
	        InputSource is = new InputSource();
	        is.setCharacterStream(new StringReader(json));

	        Document doc = db.parse(is);
	        NodeList nodes = doc.getElementsByTagName("htmlTooltip");

	        Element element = (Element) nodes.item(0);
           
	        tooltip = element.getTextContent();
	        //System.out.println(element.getTextContent());
	    }
	    catch (Exception e) {
	        e.printStackTrace();
	    }
	    return tooltip;
	}
	
	public JSONObject getItemDataBattleNet(int item_id){
		
		JSONObject stats = null;
		
		String json = loadURL("http://eu.battle.net/api/wow/item/" + item_id);
		//System.out.println(json);
		try {
           stats = new JSONObject(json);
	    }
	    catch (Exception e) {
	        e.printStackTrace();
	    }
	    return stats;
	}
	
	public Item getItem(int item_id) {
		Item item = new ItemEquiped();
		try {
			JSONObject json = getItemDataBattleNet(item_id);
			System.out.println(json.toString(1));
			item.setId(json.getInt("id"));
			item.setName(json.getString("name"));
			item.setIcon(json.getString("icon"));
			item.setInventoryType(json.getInt("inventoryType"));
			item.setItemLevel(json.getInt("itemLevel"));
			item.setQuality(json.getInt("quality"));
			if(json.has("heroic"))
				item.setHeroic(json.getInt("heroic"));
			JSONArray stats = json.getJSONArray("bonusStats");
			for (int i = 0;i < stats.length(); i++ )
			{
				JSONObject stat = (JSONObject) stats.get(i);
				if(stat.getInt("stat") == 3){
					 item.setAgi(stat.getInt("amount"));
				 }
				 else if(stat.getInt("stat") == 7){
					 item.setSta(stat.getInt("amount"));
				 }
				 else if(stat.getInt("stat") == 32){
					 item.setCrit(stat.getInt("amount"));
				 }
				 else if(stat.getInt("stat") == 36){
					 item.setHaste(stat.getInt("amount"));
				 }
				 else if(stat.getInt("stat") == 31){
					 item.setHit(stat.getInt("amount"));
				 }
				 else if(stat.getInt("stat") == 37){
					 item.setExp(stat.getInt("amount"));
				 }
				 else if(stat.getInt("stat") == 49){
					 item.setMastery(stat.getInt("amount"));
				 }
			}
			if(json.has("itemSet")){
				// yeah it's part of a set
				String setname = itemSetDB.getItemSetByItemId(json.getInt("id"));
				//System.out.println("setname:" + setname);
				item.setSet(setname);
				/*if(!base.getSetItems().containsKey(setname))
					base.getSetItems().put(setname, 1);
				else
					base.getSetItems().put(setname, base.getSetItems().get(setname)+1);*/
				// TODO evtl. noch benoetigt
    	   }
			if(json.has("socketInfo")){
				JSONObject socketInfo = (JSONObject)json.get("socketInfo");
				JSONArray sockets = socketInfo.getJSONArray("sockets");
				item.setNumSockets(sockets.length());
				
				Arrays.fill(item.gemSlot, "");
				for(int i = 0; i < sockets.length();i++){
					//System.out.println( ((JSONObject)sockets.get(i)).getString("type"));
					item.gemSlot[i] = ((JSONObject)sockets.get(i)).getString("type");
				}
				SocketBonus sb = null;
			    sb = getSocketBonus(json.getInt("id"));
			    item.socketBonus = sb;
			}
			if(json.getInt("inventoryType") == 6){
				int i = ((JSONObject)json.get("socketInfo")).getJSONArray("sockets").length();
				System.out.println( "PRISMATIC");
				item.gemSlot[i] = "PRISMATIC";
				item.setNumSockets(i+1);
			}
			if(json.has("weaponInfo")){
				item.setItemSubClass(json.getInt("itemSubClass"));
				item.speed = json.getJSONObject("weaponInfo").getDouble("weaponSpeed");
				item.dps = json.getJSONObject("weaponInfo").getDouble("dps");
				item.minDmg = json.getJSONObject("weaponInfo").getJSONObject("damage").getInt("min");
				item.maxDmg = json.getJSONObject("weaponInfo").getJSONObject("damage").getInt("max");
			}
			
			if(json.getJSONArray("itemSpells").length() > 0){
				System.out.println("gearbuff_existing");
				GearBuffDB.GearBuff gearbuff = gearBuffDB.getGearBuff(item_id);
				if(gearbuff != null){
					//base.addGearBuff(gearbuff.getName());
					item.setGearBuff(gearbuff.getName());
				}
			}
		}
	    catch (Exception e) {
	        e.printStackTrace();
	    }
	    return item;
	}
	
	public ItemEquiped getItemFromWOWHEAD(int itemid){
		ItemEquiped item = new ItemEquiped();
		
		JSONObject data = getItemDataWowHead(itemid);
		JSONObject extra;
		try {
			extra = data.getJSONObject("extra");

			//System.out.println(data.toString(1));
			
			item.setName(data.getString("name"));
			item.setIcon(data.getString("icon"));
			if(data.has("str"))
				item.setStr(data.getInt("str"));
			if(data.has("agi"))
				item.setAgi(data.getInt("agi"));
			if(data.has("sta"))
				item.setSta(data.getInt("sta"));
			if(data.has("hitrtng"))
				item.setHit(data.getInt("hitrtng"));
			if(data.has("critstrkrtng"))
				item.setCrit(data.getInt("critstrkrtng"));
			if(data.has("hastertng"))
				item.setHaste(data.getInt("hastertng"));
			if(data.has("exprtng"))
				item.setExp(data.getInt("exprtng"));
			if(data.has("mastrtng"))
				item.setMastery(data.getInt("mastrtng"));
			
			if(extra.has("id"))
				item.setId(extra.getInt("id"));
			if(data.has("dps"))
				item.dps = data.getDouble("dps");
			if(data.has("mledmgmax"))
				item.maxDmg = data.getInt("mledmgmax");
			if(data.has("mledmgmin"))
				item.minDmg = data.getInt("mledmgmin");
			if(data.has("speed"))
				item.speed = data.getDouble("speed");
			if(extra.has("level"))
				item.setItemLevel(extra.getInt("level"));
			if(extra.has("subclass"))
				item.setItemSubClass(extra.getInt("subclass"));
			if(extra.has("slot"))
				item.setInventoryType(extra.getInt("slot"));
			
			// socket colors and socketbonus
			if(data.has("nsockets"))
				item.setNumSockets(data.getInt("nsockets"));
			if(data.has("socket1"))
				item.gemSlot[0] = Gem.Colors[data.getInt("socket1")];
			if(data.has("socket2"))
				item.gemSlot[1] = Gem.Colors[data.getInt("socket2")];
			if(data.has("socket3"))
				item.gemSlot[2] = Gem.Colors[data.getInt("socket3")];
			if(data.has("socketbonus"))
				item.socketBonus = socketbonusDB.getSocketBonus(data.getInt("socketbonus"));
			
			// item set
			if(data.has("itemset"))
				item.setSet(itemSetDB.getItemSetByItemId(itemid));
			GearBuffDB.GearBuff gb = gearBuffDB.getGearBuff(itemid);
			if(gb != null){
				System.out.println(gb.getName());
				item.setGearBuff(gb.getName());
			}
			
		
		} catch (JSONException e) {
			e.printStackTrace();
		}
		
		return item;
	}
	
	public BaseStats getBase(){
		return base;
	}
	
	public HashMap<String, Integer> getItems(){
		return items;
	}

	public Equipment getEquipment() {
		return equipment;
	}
	
	public void setDatabase(Database db){
		this.db = db;
	}
	
	public Database getDatabase(){
		return db;
	}

	public GemDB getGemDB() {
		return gemDB;
	}

	public EnchantDB getEnchantDB() {
		return enchantDB;
	}

	public ReforgeDB getReforgeDB() {
		return reforgeDB;
	}
}
